package com.own.business.message.center.controller.user;

import com.own.business.message.center.business.service.MessageCenterContentService;
import com.own.business.message.center.controller.user.entity.query.NextLatestQuery;
import com.own.business.message.center.controller.user.entity.vo.MessageCenterContentCacheVo;
import com.own.business.message.center.controller.user.open.UserMessageCenterContentOpen;
import com.own.business.message.center.entity.query.MessageCenterContentQuery;
import com.own.business.message.center.entity.vo.MessageCenterContentVo;
import com.own.component.common.base.controller.BaseController;
import com.own.component.common.exception.BusinessSimpleException;
import com.own.component.common.login.util.SessionUserUtil;
import com.own.component.common.model.PageModel;
import com.own.component.common.model.R;
import com.own.component.common.model.ResultModel;
import com.own.component.common.util.executor.ExecutorUtil;
import com.own.component.log.operation.aop.LogOperationAop;
import com.own.component.log.operation.aop.LogOperationModuleAop;
import com.own.component.store.core.confirm.aop.ConfirmAop;
import com.own.constant.ConstantApiPrefix;
import com.own.constant.ConstantBeanSuffix;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.ZoneOffset;

/**
 * UserMessageCenterContentController
 *
 * @author chenxueli
 * @date 2023-11-13 14:39:27
 */
@Tag(name = "消息中心内容" + ConstantBeanSuffix.USER_CLIENT + ConstantBeanSuffix.CONTROLLER)
@RestController
@LogOperationModuleAop("消息中心内容" + ConstantBeanSuffix.USER_CLIENT)
@RequestMapping(ConstantApiPrefix.BASE_API_V1_PREFIX + ConstantApiPrefix.USER_CLIENT + "message/center/content")
public class UserMessageCenterContentController extends BaseController {

    @Resource
    private MessageCenterContentService messageCenterContentService;
    @Resource
    private UserMessageCenterContentOpen userMessageCenterContentOpen;

    @Resource
    private ExecutorUtil executorUtil;

    @Operation(summary = "根据时间戳查询之后的n条信息")
    @PostMapping("/next")
    public ResultModel<MessageCenterContentCacheVo> all(
            @RequestBody NextLatestQuery query
    ) {
        var loginUser = SessionUserUtil.getLoginUser();
        // 获取当前的时间戳
        var vo = new MessageCenterContentCacheVo();
        query.check();
        var pageModel = messageCenterContentService.next(loginUser.userId(), query.getTimestamp(), query.getLimit());
        vo.setList(pageModel.getList());
        vo.setIsLastPage(pageModel.getIsLastPage());
        // 获取最后一条数据的时间戳
        if (!pageModel.getList().isEmpty()) {
            vo.setTimestamp(pageModel.getList().getLast().getGmtCreate().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        } else {
            vo.setTimestamp(System.currentTimeMillis());
        }
        return R.success(vo);
    }

    @LogOperationAop
    @Operation(summary = "分页查询信息")
    @PostMapping("/page")
    public ResultModel<PageModel<MessageCenterContentVo>> pageForGroupKey(
            @RequestBody MessageCenterContentQuery query
    ) {
        var pageModel = userMessageCenterContentOpen.pageForGroupKey(query);
        return R.success(pageModel);
    }

    @LogOperationAop
    @ConfirmAop(message = "确认删除该项目？（注意：删除之后无法找回数据，且该项目所有资料会被删除）")
    @Operation(summary = "删除信息")
    @DeleteMapping("/{messageCenterContentId}")
    public ResultModel<Boolean> delete(
            @Parameter(description = "主键id", required = true) @PathVariable Long messageCenterContentId
    ) {
        var updateModel = messageCenterContentService.delete(messageCenterContentId);
        return R.success(updateModel);
    }

    @LogOperationAop
    @Operation(summary = "根据id获取信息")
    @GetMapping("/{messageId}")
    public ResultModel<MessageCenterContentVo> getById(
            @Parameter(description = "主键id", required = true) @PathVariable Long messageId
    ) {
        var vo = messageCenterContentService.getById(messageId);
        if (vo.getIsRead() == 0) {
            vo.setIsRead(1);
            // 设置消息已读
            executorUtil.execute(() -> read(messageId));
        }
        return R.success(vo);
    }

    @LogOperationAop
    @Operation(summary = "设置消息已读")
    @PostMapping("/read/{messageId}")
    public ResultModel<Boolean> read(
            @Parameter(description = "主键id", required = true) @PathVariable Long messageId
    ) {
        var loginUser = SessionUserUtil.getLoginUser();
        messageCenterContentService.read(loginUser.userId(), messageId);
        return R.success(true);
    }

    @LogOperationAop
    @Operation(summary = "未读消息数")
    @PostMapping("/count/unread")
    public ResultModel<Long> countUnread() {
        var loginUser = SessionUserUtil.getLoginUser();
        var count = messageCenterContentService.countUnread(loginUser.userId());
        return R.success(count);
    }

    @LogOperationAop
    @Operation(summary = "一键已读")
    @PostMapping("/batch/read")
    public ResultModel<Boolean> batchRead() {
        var loginUser = SessionUserUtil.getLoginUser();
        messageCenterContentService.batchRead(loginUser.userId());
        return R.success(true);
    }

    @LogOperationAop
    @Operation(summary = "一键已读（分组key）")
    @PostMapping("/batch/read/group")
    public ResultModel<Boolean> batchReadByGroupKey(
            @Parameter(description = "分组key", required = true) @RequestParam(required = false) String groupKey
    ) {
        if (StringUtils.isBlank(groupKey)) {
            throw new BusinessSimpleException("分组key不能为空");
        }
        var loginUser = SessionUserUtil.getLoginUser();
        messageCenterContentService.batchRead(loginUser.userId(), groupKey);
        return R.success(true);
    }

}
